package model;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;

/**.
 * Class used to get movie information via API
 * @author jaubertbenjamin
 *
 */
public final class MoviesInfosFinder {

    /**.
     * Default constructor
    */
    private MoviesInfosFinder() {
       //do nothing
    }

    /**.
     * HTTP client
     */
    private static DefaultHttpClient httpClient;
    /**.
     * HTTP get request
     */
    private static HttpGet getRequest;
    /**.
     * HTTP response
     */
    private static HttpResponse response;
    /**.
     * buffered reader
     */
    private static BufferedReader reader;
    /**.
     * output
     */
    private static String output;
    /**.
     * JSON factory
     */
    private static JsonFactory jFactory;
    /**.
     * JSON parser
     */
    private static JsonParser parser;

    /**.
     * Get informations of all the movies from the omdb API
     * @param moviesList the movie list
     * @return the movie list
     */
    public static MoviesList getMoviesInfos(MoviesList moviesList) {
        httpClient = new DefaultHttpClient();
        for (int i = 0; i < moviesList.getMovies().size(); i++) {
            getRequest = new HttpGet("http://www.omdbapi.com/?t="+moviesList.getMovies().get(i).getSearch()+"&tomatoes=true");
            getRequest.addHeader("accept", "application/json");
            try {
               response = httpClient.execute(getRequest);

               if (response.getStatusLine().getStatusCode() != 200) {
                    throw new RuntimeException("Failed : HTTP error code : "+ response.getStatusLine().getStatusCode());
               }

                reader = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
                output = reader.readLine();
                moviesList = parseJSON(moviesList, i);
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        httpClient.getConnectionManager().shutdown();

        return moviesList;
    }

    /**.
     * This function is used to parse the json received and to complete the corresponding movie object.
     * @param moviesList the movie List
     * @param i the current position in the list
     * @return the movie list
     */
    public static MoviesList parseJSON(final MoviesList moviesList, final int i) {
        jFactory = new JsonFactory();
        try {
            parser = jFactory.createJsonParser(output);

            while (parser.nextToken() != JsonToken.END_OBJECT) {
                String fieldname = parser.getCurrentName();

                if ("Title".equals(fieldname)) {
                    parser.nextToken();
                    moviesList.getMovies().get(i).setTitle(parser.getText());
                }
                if ("Year".equals(fieldname)) {
                    parser.nextToken();
                    moviesList.getMovies().get(i).setYear(Integer.parseInt(parser.getText()));
                    moviesList.getMovies().get(i).setCompleted(true);
                }
                if ("Rated".equals(fieldname)) {
                    parser.nextToken();
                    moviesList.getMovies().get(i).setClassification(parser.getText());
                }
                if ("Released".equals(fieldname)) {
                    parser.nextToken();
                    moviesList.getMovies().get(i).getRelease().setTheater(parser.getText());
                }
                if ("Runtime".equals(fieldname)) {
                    parser.nextToken();
                    moviesList.getMovies().get(i).setRuntime(parser.getText());
                }
                if ("Genre".equals(fieldname)) {
                    parser.nextToken();
                    String[] str = parser.getText().split("\\,");
                    for (int j = 0; j < str.length; j++) {
                        moviesList.getMovies().get(i).addGenre(str[j].replaceAll("^\\s+", ""));
                    }
                }
                if ("Director".equals(fieldname)) {
                    parser.nextToken();
                    String[] str = parser.getText().split("\\,");
                    for (int j = 0; j < str.length; j++) {
						moviesList.getMovies().get(i).addDirector(str[j].replaceAll("^\\s+", ""));
					}
				}
				if ("Writer".equals(fieldname)) {
					parser.nextToken();
					String[] str = parser.getText().split("\\,");
					for (int j = 0; j < str.length; j++) {
						moviesList.getMovies().get(i).addWriter(str[j].replaceAll("^\\s+", ""));
					}
				}
				if ("Actors".equals(fieldname)) {
					parser.nextToken();
					String[] str = parser.getText().split("\\,");
					for (int j = 0; j < str.length; j++) {
						moviesList.getMovies().get(i).addActors(str[j].replaceAll("^\\s+", ""));
					}
				}
				if ("Plot".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setPlot(parser.getText());
				}
				if ("Poster".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setPoster(parser.getText());
				}
				if ("imdbRating".equals(fieldname)) {
					parser.nextToken();
					if (!parser.getText().equals("N/A")) {
						moviesList.getMovies().get(i).getRating().setImdbRating(Float.valueOf(parser.getText()));
					}
				}
				if ("tomatoMeter".equals(fieldname)) {
					parser.nextToken();
					if (!parser.getText().equals("N/A")) {
						moviesList.getMovies().get(i).getRating().setTomatoMeter(Float.valueOf(parser.getText())/10);
					}
				}
				if ("tomatoImage".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).getRating().setTomatoImage(parser.getText());
				}
				if ("tomatoConsensus".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).getRating().setCritic(parser.getText());
				}
				if ("tomatoUserMeter".equals(fieldname)) {
					parser.nextToken();
					if (!parser.getText().equals("N/A")) {
						moviesList.getMovies().get(i).getRating().setTomatoUserMeter(Float.valueOf(parser.getText())/10);
					}
				}
				if ("DVD".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).getRelease().setDvd(parser.getText());
				}
				if ("BoxOffice".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setBoxOffice(parser.getText());
				}
				if ("Production".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setProduction(parser.getText());
				}
				if ("Website".equals(fieldname)) {
					parser.nextToken();
					moviesList.getMovies().get(i).setWebsite(parser.getText());
					if (moviesList.getMovies().get(i).getPoster().equals("N/A")) {
						moviesList.getMovies().get(i).setCompleted(false);
					} else {
						moviesList.getMovies().get(i).setCompleted(true);
					}
				}
			}
		} catch (JsonParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return moviesList;
	}

}
